package com.kavin.design.singleton;

/**
 * @author kavin
 * @Description 线程安全的懒汉式单例。双重锁+ volatile 禁止指令重排 编写高效安全的懒汉单例模式。
 * @create 2020/6/24
 **/
public class SafeLazySingleton {
    private static volatile SafeLazySingleton singleton;//第二层锁，volatile关键字禁止指令重排，保证返回Singleton对象一定在创建对象后

    //参考地址：https://blog.csdn.net/Jarbein/article/details/102495075
    public static SafeLazySingleton getInstance(){
        if(singleton==null){   //此处判断主要是优化，为了防止进入下一行代码进行锁等待。
            synchronized (SafeLazySingleton.class){   //第一层锁，保证只有一个线程进入
                    if(singleton==null){   //为了阻止已经进入第一个singleton==null 且没拿到锁的线程进入synchronized代码块进行多次创建。（防止对象多次创建）
                        singleton=new SafeLazySingleton();  //volatile 使singleton的更新立即被刷到主内存。如果不加，在没有跳出synchronized块之前，singleton在工作内存已经更新，但是在主内存还可能为null。这样就会导致后续来的线程又进入第一个singleton==null的条件判断。
                }
            }
        }
        return singleton;
    }


}
